#include "aluno.h"

/**
 * Cria um novo aluno.
 */
int create_aluno(Aluno *aluno) {
    FILE *file = NULL;

    // busca proxima matricula válida
    aluno->matricula = next_sequence(ALUNO_SEQ);
    if (aluno->matricula != NOT_FOUND) {
        file = fopen(ALUNO_DB, "ab+");
        if (file) {
            if (!fwrite(aluno, sizeof (Aluno), 1, file)) {
                printf(CREATE_ERROR, "aluno");
                fclose(file);
                return PROC_FAILURE;
            }
            fclose(file);
        } else {
            printf(OPEN_FILE_ERROR, ALUNO_DB);
            return PROC_FAILURE;
        }
        return PROC_SUCCESS;
    } else {
        return PROC_FAILURE;
    }
}

int read_aluno(int matricula) {
    FILE *file = NULL;
    Aluno *aluno;
    Curso *curso = NULL;

    file = fopen(ALUNO_DB, "rb");
    if (file) {
        aluno = (Aluno *) malloc(sizeof (Aluno));
        if (!aluno) {
            printf(INSUFICIENT_MEMORY, "Aluno");
            return PROC_FAILURE;
        }
        printf("Dados do Aluno\n");
        printf("%-10s %-25s %-25s\n", "Matricula", "Nome", "Curso");
        puts("---------- ------------------------- -------------------------");
        fread(aluno, sizeof (Aluno), 1, file);
        while (!feof(file)) {
            if (aluno->matricula == matricula) {
                curso = get_curso(aluno->curso_id);
                printf("%010d %-25s %-25s\n", aluno->matricula, aluno->nome,
                        curso->descricao);
                break;
            }
            fread(aluno, sizeof (Aluno), 1, file);
        }
        fclose(file);
        return PROC_SUCCESS;
    } else {
        printf(OPEN_FILE_ERROR, ALUNO_DB);
        return PROC_FAILURE;
    }
}

int read_all_aluno() {
    FILE *file = NULL;
    Aluno *aluno = NULL;
    Curso *curso = NULL;

    file = fopen(ALUNO_DB, "rb");
    if (file) {
        aluno = (Aluno *) malloc(sizeof (Aluno));
        if (!aluno) {
            printf(INSUFICIENT_MEMORY, "Aluno");
            return PROC_FAILURE;
        }
        printf("Lista de Alunos\n");
        printf("%-10s %-25s %-25s %-10s\n", "Matricula", "Nome", "Curso", "COD Curso");
        puts("---------- ------------------------- ------------------------- ----------");
        fread(aluno, sizeof (Aluno), 1, file);
        while (!feof(file)) {
            curso = get_curso(aluno->curso_id);
            printf("%010d %-25s %-25s %010d\n",
                    aluno->matricula, aluno->nome, curso->descricao, aluno->curso_id);
            fread(aluno, sizeof (Aluno), 1, file);
        }
        printf("\n\n");
        fclose(file);
        free(curso);
        free(aluno);
        return PROC_SUCCESS;
    } else {
        printf(OPEN_FILE_ERROR, ALUNO_DB);
        return PROC_FAILURE;
    }
}

Aluno * find_aluno(char *input, Buscar_por buscar_por) {
    FILE *file = NULL;
    Aluno *aluno = NULL;
    int search_matricula;

    file = fopen(ALUNO_DB, "rb");
    if (file) {
        aluno = (Aluno *) malloc(sizeof (Aluno));
        if (!aluno) {
            printf(INSUFICIENT_MEMORY, "Aluno");
            return NULL;
        }
        /* lê a primeira vez para evitar fim do arquivo na primeira linha. */
        fread(aluno, sizeof (Aluno), 1, file);
        if (buscar_por == nome) {
            while (!feof(file)) {
                if (!strcmp(input, aluno->nome)) {
                    fclose(file);
                    return aluno;
                }
                /* continua lendo o arquivo. */
                fread(aluno, sizeof (Aluno), 1, file);
            }
        } else if (buscar_por == matricula) {
            search_matricula = atoi(input);
            while (!feof(file)) {
                if (aluno->matricula == search_matricula) {
                    fclose(file);
                    return aluno;
                }
                /* continua lendo o arquivo. */
                fread(aluno, sizeof (Aluno), 1, file);
            }
        }
    } else {
        printf(OPEN_FILE_ERROR, ALUNO_DB);
    }
    fclose(file);
    aluno->matricula = NOT_FOUND;
    return aluno;
}

/**
 * @deprecated
 * @param nome
 * @return
 */
Aluno * find_aluno_by_nome(char *nome) {
    FILE *file = NULL;
    Aluno *aluno = NULL;

    file = fopen(ALUNO_DB, "rb");
    if (file) {
        aluno = (Aluno *) malloc(sizeof (Aluno));
        if (!aluno) {
            printf(INSUFICIENT_MEMORY, "Aluno");
            return NULL;
        }
        /* lê a primeira vez para evitar fim do arquivo na primeira linha. */
        fread(aluno, sizeof (Aluno), 1, file);
        while (!feof(file)) {
            if (!strcasecmp(nome, aluno->nome)) {
                fclose(file);
                return aluno;
            }
            /* continua lendo o arquivo. */
            fread(aluno, sizeof (Aluno), 1, file);
        }
    } else {
        printf(OPEN_FILE_ERROR, ALUNO_DB);
    }
    fclose(file);
    aluno->matricula = NOT_FOUND;
    return aluno;
}

int aluno_size() {
    FILE *file = NULL;

    file = fopen(ALUNO_DB, "rb");
    if (file) {
        fseek(file, 0, SEEK_END);
        int size = ftell(file) / sizeof (Aluno);
        fclose(file);
        return size;
    } else {
        printf(READ_ERROR, CURSO_DB);
        fclose(file);
        return NOT_FOUND;
    }
}

int delete_aluno(int matricula) {
    FILE *file = NULL, *file_tmp = NULL;
    Aluno *aluno_aux = NULL;

    file = fopen(ALUNO_DB, "rb+");
    if (file) {
        file_tmp = fopen(ALUNO_TMP, "wb");
        if (file_tmp) {
            aluno_aux = (Aluno *) malloc(sizeof (Aluno));
            if (!aluno_aux) {
                printf(INSUFICIENT_MEMORY, "Aluno");
                return PROC_FAILURE;
            }
            fread(aluno_aux, sizeof (Aluno), 1, file);
            while (not feof(file)) {
                if (aluno_aux->matricula != matricula) {
                    fwrite(aluno_aux, sizeof (Aluno), 1, file_tmp);
                }
                fread(aluno_aux, sizeof (Aluno), 1, file);
            }
            free(aluno_aux);
            fclose(file);
            fclose(file_tmp);

            if (remove(ALUNO_DB) != PROC_SUCCESS) {
                printf(DEL_FILE_ERROR, ALUNO_DB);
                return PROC_FAILURE;
            }
            if (rename(ALUNO_TMP, ALUNO_DB) != PROC_SUCCESS) {
                printf(RENAME_FILE_ERROR, ALUNO_DB);
                return PROC_FAILURE;
            }
            return PROC_SUCCESS;
        } else {
            printf(CREATE_FILE_ERROR, ALUNO_TMP);
            return PROC_FAILURE;
        }
    } else {
        printf(OPEN_FILE_ERROR, ALUNO_DB);
        return PROC_FAILURE;
    }
}